package com.astrofizzbizz.stoneedgegui.app;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

import com.astrofizzbizz.stoneedgegui.simbad.TargetInformation;
import com.astrofizzbizz.stoneedgegui.utilities.SkyTargetChart;
import com.astrofizzbizz.stoneedgegui.utilities.StarCoordUtilities;
import com.astrofizzbizz.stoneedgegui.utilities.StoneEdgeIIIException;
import com.astrofizzbizz.stoneedgegui.utilities.Utilities;


import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;


public class TargetingPanel extends JPanel
{
	private static final long serialVersionUID = 3095246671005387641L;
	private int chartSize = 500;
	private double latitude = 38.29341507;
	private double longitude = -122.47058868;
	private JLabel lstTime = new JLabel("");
	private JLabel obsTime = new JLabel("");
	private JLabel gmtTime = new JLabel("");
	private JLabel locTime = new JLabel("");
	private JLabel currentRa = new JLabel("", SwingConstants.RIGHT);
	private JLabel currentDec = new JLabel("", SwingConstants.RIGHT);
	private JLabel currentTarget = new JLabel("", SwingConstants.RIGHT);
	private StoneEdgeIIIGui stoneEdgeIIIGui;
	private JTextField targetTextField = new JTextField("Target Name");
	private JTextField raHrsTextField = new JTextField(3);
	private JTextField raMinTextField = new JTextField(3);
	private JTextField raSecTextField = new JTextField(10);

	private JTextField decDegTextField = new JTextField(3);
	private JTextField decMinTextField = new JTextField(3);
	private JTextField decSecTextField = new JTextField(10);
	
	private JButton updateTargetButton = new JButton("Update");
	private JButton slewButton = new JButton("Slew");
	
	private AstroTarget astroTarget = null;

	SkyTargetChart skyTargetChart;
	
	public TargetingPanel(StoneEdgeIIIGui stoneEdgeIIIGui)
	{
		super();
		this.stoneEdgeIIIGui = stoneEdgeIIIGui;
		add(timePanel());
		add(currentPositionPanel());
		try {
			currentRa.setText(StarCoordUtilities.raString(stoneEdgeIIIGui.getTelescopeInfo().getRaDeg()));
			currentDec.setText(StarCoordUtilities.decString(stoneEdgeIIIGui.getTelescopeInfo().getDecDeg()));
			currentTarget.setText("Current");
			astroTarget = new AstroTarget("Current", currentRa.getText(), currentDec.getText(),stoneEdgeIIIGui);} 
		catch (StoneEdgeIIIException e) {e.messageDialog(stoneEdgeIIIGui);}
		this.stoneEdgeIIIGui = stoneEdgeIIIGui;
		skyTargetChart = new SkyTargetChart(chartSize , latitude, longitude, 
				stoneEdgeIIIGui.getTelescopeInfo().getAzDeg(), stoneEdgeIIIGui.getTelescopeInfo().getAltDeg(), astroTarget.getAzDeg(), astroTarget.getAltDeg(), 
				stoneEdgeIIIGui.getUpdateDate());
		add(skyTargetChart);
		add(raDecPanel());
	}
	private JPanel timePanel()
	{
		JPanel timePanel = new JPanel();
		timePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Time"),BorderFactory.createEmptyBorder(5,5,5,5)));
		timePanel.setLayout(new GridLayout(4,2));
		obsTime.setText(StarCoordUtilities.getTimeString(stoneEdgeIIIGui.getUpdateDate(), "America/Los_Angeles"));
		gmtTime.setText(StarCoordUtilities.getTimeString(stoneEdgeIIIGui.getUpdateDate(), "GMT"));
		locTime.setText(StarCoordUtilities.getDefaultTimeString(stoneEdgeIIIGui.getUpdateDate()));
        String lst = StarCoordUtilities.raString(StarCoordUtilities.lmstDeg(stoneEdgeIIIGui.getUpdateDate(), 
        		stoneEdgeIIIGui.getTelescopeInfo().getLongitudeDeg()));
        lst = lst.substring(0, lst.lastIndexOf("."));
		lstTime.setText(lst);
		timePanel.add(new JLabel("Local Sidereal "));
		timePanel.add(lstTime);
		timePanel.add(new JLabel("Observatory"));
		timePanel.add(obsTime);
		timePanel.add(new JLabel("Greenwich Mean"));
		timePanel.add(gmtTime);
		timePanel.add(new JLabel("Local"));
		timePanel.add(locTime);
		
		return timePanel;
		
	}
	private JPanel currentPositionPanel()
	{
		JPanel currentPositionPanel = new JPanel();
		currentPositionPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("Current Position"),BorderFactory.createEmptyBorder(5,5,5,5)));
		currentPositionPanel.setLayout(new GridLayout(4,2));
		currentTarget.setVerticalAlignment(SwingConstants.CENTER);
		currentRa.setVerticalAlignment(SwingConstants.CENTER);
		currentDec.setVerticalAlignment(SwingConstants.CENTER);
		currentTarget.setForeground(Color.BLUE);
		currentRa.setForeground(Color.BLUE);
		currentDec.setForeground(Color.BLUE);
		currentPositionPanel.add(new JLabel("Name"));
		currentPositionPanel.add(currentTarget);
		currentPositionPanel.add(new JLabel("R.A."));
		currentPositionPanel.add(currentRa);
		currentPositionPanel.add(new JLabel("Dec"));
		currentPositionPanel.add(currentDec);
		
		return currentPositionPanel;
		
	}
	private JPanel raDecPanel()
	{
		
		JPanel raDecPanel = new JPanel();

		targetTextField.setForeground(Color.GREEN.darker());
		raHrsTextField.setForeground(Color.GREEN.darker());
		raMinTextField.setForeground(Color.GREEN.darker());
		raSecTextField.setForeground(Color.GREEN.darker());
		decDegTextField.setForeground(Color.GREEN.darker());
		decMinTextField.setForeground(Color.GREEN.darker());
		decSecTextField.setForeground(Color.GREEN.darker());

		raDecPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createTitledBorder("RA Dec"),BorderFactory.createEmptyBorder(5,5,5,5)));
		raDecPanel.setLayout(new GridLayout(3,7));
		raDecPanel.add(new JLabel("Target"));
		raDecPanel.add(targetTextField);
		raDecPanel.add(new JLabel(""));
		raDecPanel.add(updateTargetButton);
		raDecPanel.add(new JLabel(""));
		updateTargetButton.setVisible(false);
		updateTargetButton.addActionListener(new TargetingPanelListener("updateTarget"));
		if (stoneEdgeIIIGui.getTelescopeMonitorPanel().getDomeMonitorPanel().getDomeMonitor().isOurLockOn())
		{
			slewButton.setVisible(true);
		}
		else
		{
			slewButton.setVisible(false);
		}
		slewButton.addActionListener(new TargetingPanelListener("slew"));
		raDecPanel.add(slewButton);
		raDecPanel.add(new JLabel(""));

		raDecPanel.add(new JLabel("R.A."));
		raDecPanel.add(raHrsTextField);
		raDecPanel.add(new JLabel("Hrs"));
		raDecPanel.add(raMinTextField);
		raDecPanel.add(new JLabel("min."));
		raDecPanel.add(raSecTextField);
		raDecPanel.add(new JLabel("sec."));

		raDecPanel.add(new JLabel("Dec."));
		raDecPanel.add(decDegTextField);
		raDecPanel.add(new JLabel("deg"));
		raDecPanel.add(decMinTextField);
		raDecPanel.add(new JLabel("min."));
		raDecPanel.add(decSecTextField);
		raDecPanel.add(new JLabel("sec."));
		
		targetTextField.addMouseListener(new TargetingPanelListener("target"));
		raHrsTextField.addMouseListener(new TargetingPanelListener("raHrs"));
		raMinTextField.addMouseListener(new TargetingPanelListener("raMin"));
		raSecTextField.addMouseListener(new TargetingPanelListener("raSec"));
		decDegTextField.addMouseListener(new TargetingPanelListener("decHrs"));
		decMinTextField.addMouseListener(new TargetingPanelListener("decMin"));
		decSecTextField.addMouseListener(new TargetingPanelListener("decSec"));
		return raDecPanel;
	}
	
	private void changeTextFieldColor(Color color)
	{
		targetTextField.setForeground(color);
		raHrsTextField.setForeground(color);
		raMinTextField.setForeground(color);
		raSecTextField.setForeground(color);
		decDegTextField.setForeground(color);
		decMinTextField.setForeground(color);
		decSecTextField.setForeground(color);
	}
	private void updateTargetCoordinateFromTextfields()
	{
		String ra = Utilities.stripWhiteSpaces(raHrsTextField.getText()) + ":";
		ra  = ra +  Utilities.stripWhiteSpaces(raMinTextField.getText()) + ":";
		ra  = ra +  Utilities.stripWhiteSpaces(raSecTextField.getText());
		String dec = Utilities.stripWhiteSpaces(decDegTextField.getText()) + ":";
		dec  = dec + Utilities.stripWhiteSpaces(decMinTextField.getText()) + ":";
		dec  = dec + Utilities.stripWhiteSpaces(decSecTextField.getText());
		try 
		{
			StarCoordUtilities.raStringOk(ra);
			StarCoordUtilities.decStringOk(dec);
			String newTarget = Utilities.stripSpecialCharacters(Utilities.stripWhiteSpaces(targetTextField.getText()));
			targetTextField.setText(newTarget);
			AstroTarget checkTarget = new AstroTarget(newTarget, ra, dec, stoneEdgeIIIGui);
			if (checkTarget.isVisible())
			{
				if (astroTarget.getName().equals(newTarget))
				{
					astroTarget.setRa(ra);
					astroTarget.setDec(dec);
				}
				else
				{
					astroTarget = checkTarget;
					stoneEdgeIIIGui.getAstroCatalog().setSelectedTarget(-1);
				}
			}
			else
			{
				//TODO update target check visibilkity  - figure out why so slow
				stoneEdgeIIIGui.messageDialog("Target not visibile");
			}
			changeTextFieldColor(Color.GREEN.darker());
			updateTargetButton.setVisible(false);
			
		} catch (StoneEdgeIIIException e) 
		{
			e.messageDialog(stoneEdgeIIIGui);
			updateTargetButton.setVisible(false);
			try {setAstroTarget(astroTarget);} 
			catch (StoneEdgeIIIException e1) 
			{
				e.messageDialog(stoneEdgeIIIGui);
			}
		}
		try {update();} 
		catch (StoneEdgeIIIException e) 
		{
			e.messageDialog(stoneEdgeIIIGui);
		}
	}
	public void update() throws StoneEdgeIIIException
	{
		if (updateTargetButton.isVisible()) return;
		
		astroTarget.update();
			
		String[] raHrsMinsSecs = StarCoordUtilities.getRaHrsMinsSecs(astroTarget.getRa());
		getRaHrsTextField().setText(raHrsMinsSecs[0]);
		getRaMinTextField().setText(raHrsMinsSecs[1]);
		getRaSecTextField().setText(raHrsMinsSecs[2]);
		
		String[] decDegMinsSecs = StarCoordUtilities.getDecDegMinsSecs(astroTarget.getDec());
		
		getDecDegTextField().setText(decDegMinsSecs[0]);
		getDecMinTextField().setText(decDegMinsSecs[1]);
		getDecSecTextField().setText(decDegMinsSecs[2]);

		getTargetTextField().setText(astroTarget.getName());
		
		skyTargetChart.setTime(stoneEdgeIIIGui.getUpdateDate());
		skyTargetChart.setPresentAltAz(stoneEdgeIIIGui.getTelescopeInfo().getAltDeg(), stoneEdgeIIIGui.getTelescopeInfo().getAzDeg());
		skyTargetChart.setTargetAltAz(astroTarget.getAltDeg(), astroTarget.getAzDeg());
		skyTargetChart.updateChart();
		currentRa.setText(StarCoordUtilities.raString(stoneEdgeIIIGui.getTelescopeInfo().getRaDeg()));
		currentDec.setText(StarCoordUtilities.decString(stoneEdgeIIIGui.getTelescopeInfo().getDecDeg()));

		obsTime.setText(StarCoordUtilities.getTimeString(stoneEdgeIIIGui.getUpdateDate(), "America/Los_Angeles"));
		gmtTime.setText(StarCoordUtilities.getTimeString(stoneEdgeIIIGui.getUpdateDate(), "GMT"));
		locTime.setText(StarCoordUtilities.getDefaultTimeString(stoneEdgeIIIGui.getUpdateDate()));
        String lst = StarCoordUtilities.raString(StarCoordUtilities.lmstDeg(stoneEdgeIIIGui.getUpdateDate(), 
        		stoneEdgeIIIGui.getTelescopeInfo().getLongitudeDeg()));
        lst = lst.substring(0, lst.lastIndexOf("."));
		lstTime.setText(lst);
		
		if (stoneEdgeIIIGui.getTelescopeMonitorPanel().getDomeMonitorPanel().getDomeMonitor().isOurLockOn())
		{
			slewButton.setVisible(true);
		}
		else
		{
			slewButton.setVisible(false);
		}
		
	}
	public JTextField getTargetTextField() {return targetTextField;}
	public JTextField getRaHrsTextField() {return raHrsTextField;}
	public JTextField getRaMinTextField() {return raMinTextField;}
	public JTextField getRaSecTextField() {return raSecTextField;}
	public JTextField getDecDegTextField() {return decDegTextField;}
	public JTextField getDecMinTextField() {return decMinTextField;}
	public JTextField getDecSecTextField() {return decSecTextField;}
	public AstroTarget getAstroTarget() {return astroTarget;}
	
	public void setAstroTarget(AstroTarget astroTarget) throws StoneEdgeIIIException 
	{
		this.astroTarget = astroTarget;
		update();
		changeTextFieldColor(Color.GREEN.darker());

	}
	
	public void setNewTarget(TargetInformation searchRes) {
		AstroTarget newTarget;
		try {
			newTarget = new AstroTarget(searchRes.ident, searchRes.ra, searchRes.dec, this.stoneEdgeIIIGui);
		} catch (StoneEdgeIIIException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
		
		try {
			setAstroTarget(newTarget);
		} catch (StoneEdgeIIIException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return;
		}
	}
	
	private class TargetingPanelListener implements MouseListener, ActionListener
	{
		String actionString = "";
		
		private TargetingPanelListener(String actionString)
		{
			this.actionString = actionString;
		}
		@Override
		public void mouseClicked(MouseEvent arg0) {}
		@Override
		public void mouseEntered(MouseEvent arg0) {}
		@Override
		public void mouseExited(MouseEvent arg0) {}
		@Override
		public void mousePressed(MouseEvent arg0) {
			System.out.println("mousePressed on " + actionString);
			updateTargetButton.setVisible(true);
			changeTextFieldColor(Color.RED);
		}
		@Override
		public void mouseReleased(MouseEvent arg0) {}
		@Override
		public void actionPerformed(ActionEvent arg0) 
		{
			if (actionString.equals("updateTarget"))
			{
				updateTargetCoordinateFromTextfields();
			}
			if (actionString.equals("slew"))
			{
				int ichoice = stoneEdgeIIIGui.optionDialog("Slew?", "Slew the Telescope?", "Yes", "No", 2);
				if (ichoice == 1)
				{
					SlewTelescope slewTelescope = new SlewTelescope();
				    Thread slewTelescopeThread = new Thread(slewTelescope);
				    slewTelescopeThread.start();
				}
			}
			
		}
	}
	private class SlewTelescope implements Runnable
	{
		@Override
		public void run() 
		{
			String slewCommand = "tx point ra=" 
					+ astroTarget.getRa() 
					+ " dec=" + astroTarget.getDec() 
					+ " equinox=" + astroTarget.getEpoch();
System.out.println(slewCommand);
			WaitFrame waitFrame = null;
		    try 
		    {
				waitFrame = new WaitFrame("Wait", "Please wait. Slewing Telescope", stoneEdgeIIIGui);
				stoneEdgeIIIGui.getTelescopeMonitorPanel().getStatusBar().setText("Slewing Telescope...");
				stoneEdgeIIIGui.getStoneEdgeIIITunnel().executeCommand(slewCommand, 1024);
				currentTarget.setText(astroTarget.getName());
				stoneEdgeIIIGui.getTelescopeMonitorPanel().getDomeMonitorPanel().getDomeMonitor().updateMonitor();
				stoneEdgeIIIGui.getTelescopeMonitorPanel().getStatusBar().setText("Telescope at Target");
				waitFrame.dispose();
			} 
		    catch (StoneEdgeIIIException e) 
			{
		    	waitFrame.dispose();
				e.messageDialog(stoneEdgeIIIGui);
				
			}
		}
		
	}

}
